package cn.skyquant.quant4j.service.boot.model.goods;

import cn.skyquant.quant4j.api.dto.ResultDTO;
import cn.skyquant.quant4j.api.enums.BorkerType;
import cn.skyquant.quant4j.api.enums.GoodsType;
import cn.skyquant.quant4j.api.goods.GoodsDTO;
import cn.skyquant.quant4j.api.goods.GoodsService;
import cn.skyquant.quant4j.api.goods.GoodsTickDTO;
import cn.skyquant.quant4j.sdk.util.bean.BeanTools;
import com.google.common.collect.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service("GoodsServiceImpl")
public class GoodsServiceImpl implements GoodsService {
    @Resource
    GoodsRepository goodsRepository;
    @Resource
    GoodsTickRepository goodsTickRepository;

    @Override
    public ResultDTO<GoodsDTO> get(String symbol, BorkerType borkerType) {
        Optional<Goods> optionalGoods = goodsRepository.getBySymbolAndBorkerType(symbol,borkerType);
        if(optionalGoods.isPresent()){
            Goods goods = optionalGoods.get();
            GoodsDTO goodsDTO = convertDoToDTO(goods);
            return ResultDTO.success(goodsDTO);
        }
        return ResultDTO.error2;
    }

    @Override
    public ResultDTO<List<GoodsDTO>> findAllGoods(BorkerType borkerType) {
        Iterable<Goods> goodsList = goodsRepository.findByBorkerType(borkerType);
        List<GoodsDTO> goodsDTOList = Lists.newArrayList();
        goodsList.forEach(x -> goodsDTOList.add(convertDoToDTO(x)));
        return ResultDTO.success(goodsDTOList);
    }

    @Transactional
    @Override
    public ResultDTO<Void> saveGoods(String symbol, BorkerType borkerType, GoodsType type) {
        Optional<Goods> goodsOptional = goodsRepository.getBySymbolAndBorkerType(symbol,borkerType);
        if(goodsOptional.isPresent()){
            return ResultDTO.success;
        }
        Goods newGoods = new Goods(symbol,borkerType,type);
        goodsRepository.save(newGoods);
        return null;
    }

    @Transactional
    @Override
    public ResultDTO<Void> updateGoods(Integer id, GoodsType type, double avgSpread) {
        Optional<Goods> goodsOptional = goodsRepository.findById(id);
        if (goodsOptional.isPresent()) {
            Goods exist = goodsOptional.get();
            exist.avgSpread = avgSpread;
            exist.type = type;
            return ResultDTO.success;
        }
        return ResultDTO.error2;
    }

    @Override
    public ResultDTO<Void> deleteGoods(Integer id) {
        goodsRepository.deleteById(id);
        return ResultDTO.success;
    }

    @Override
    public ResultDTO<List<GoodsTickDTO>> findGoodsTickByGoodsId(Integer goodsId) {
        List<GoodsTick> goodsTickList = goodsTickRepository.findByGoodsId(goodsId, GoodsTickRepository.thedate_sort);
        List<GoodsTickDTO> goodsTickDTOList = goodsTickList.stream().map(GoodsServiceImpl::convertGoodsTickDoToDTO).collect(Collectors.toList());
        return ResultDTO.success(goodsTickDTOList);
    }

    @Override
    public ResultDTO<Void> addGoodsTick(Integer goodsId, GoodsTickDTO goodsTickDTO) {
        Optional<Goods> goodsOptional = goodsRepository.findById(goodsId);
        if (goodsOptional.isPresent()) {
            GoodsTick goodsTick = convertGoodsTickDtoToDo(goodsTickDTO);
            goodsTick.goods = goodsOptional.get();
            goodsTickRepository.save(goodsTick);
            return ResultDTO.success;
        } else {
            return ResultDTO.error2;
        }

    }

    @Override
    public ResultDTO<Void> deleteGoodsTickById(Integer id) {
        goodsTickRepository.deleteById(id);
        return ResultDTO.success;
    }

    private static GoodsDTO convertDoToDTO(Goods goods) {
        GoodsDTO goodsDTO = new GoodsDTO();
        BeanTools.copyPublicFields(goods,goodsDTO);
        return goodsDTO;
    }

    private static GoodsTickDTO convertGoodsTickDoToDTO(GoodsTick d) {
        GoodsTickDTO dto = new GoodsTickDTO();
        BeanTools.copyPublicFields(d, dto);
        return dto;
    }

    private static GoodsTick convertGoodsTickDtoToDo(GoodsTickDTO dto) {
        GoodsTick d = new GoodsTick();
        BeanTools.copyPublicFields(dto, d);
        return d;
    }
}
